From 55d0c1bc1ac594af413e2d94a56e21b0d78346dc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 29 May 2025 00:07:47 +0200 Subject: [PATCH] interface: ask for unicast responses by default When able to bind the socket without REUSEPORT, unicast responses can be received on the main port. Indicate that in outgoing questions in order to reduce unnecessary multicast traffic. Signed-off-by: Felix Fietkau --- dns.c | 2 +- interface.c | 19 ++++++++++++++----- interface.h | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/dns.c b/dns.c index 7c24ddc..18210f1 100644 --- a/dns.c +++ b/dns.c @@ -185,7 +185,7 @@ void dns_packet_send(struct interface *iface, struct sockaddr *to, bool query, i if (query) { if (multicast < 0) - multicast = interface_multicast(iface); + multicast = iface->need_multicast; for (i = 0; i < pkt_n_q; i++) dns_question_set_multicast(pkt_q[i], multicast); diff --git a/interface.c b/interface.c index 944666f..e2f0ce9 100644 --- a/interface.c +++ b/interface.c @@ -478,7 +478,7 @@ iface_update_cb(struct vlist_tree *tree, struct vlist_node *node_new, interface_start(if_new); } -static int interface_init_socket(enum umdns_socket_type type) +static int interface_init_socket(enum umdns_socket_type type, bool *mcast) { struct sockaddr_in6 local6 = { .sin6_family = AF_INET6 @@ -492,6 +492,7 @@ static int interface_init_socket(enum umdns_socket_type type) int no = 0; int fd; int af = (type & SOCKTYPE_BIT_IPV6) ? AF_INET6 : AF_INET; + bool reuseport = false; if (ufd[type].fd >= 0) return 0; @@ -501,9 +502,6 @@ static int interface_init_socket(enum umdns_socket_type type) return -1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); -#ifdef SO_REUSEPORT - setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)); -#endif switch (type) { case SOCK_UC_IPV4: @@ -524,6 +522,7 @@ static int interface_init_socket(enum umdns_socket_type type) break; } +retry: if (type & SOCKTYPE_BIT_IPV6) { ufd[type].cb = read_socket6; if (bind(fd, (struct sockaddr *)&local6, sizeof(local6)) < 0) @@ -545,6 +544,14 @@ static int interface_init_socket(enum umdns_socket_type type) return 0; error: + if (!reuseport) { +#ifdef SO_REUSEPORT + setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)); +#endif + reuseport = true; + *mcast = true; + goto retry; + } close(ufd[type].fd); return -1; } @@ -555,9 +562,10 @@ __interface_add(const char *name, enum umdns_socket_type type, { struct interface *iface; unsigned int ifindex; + bool mcast = false; char *id_buf; - if (interface_init_socket(type)) + if (interface_init_socket(type, &mcast)) goto error; ifindex = if_nametoindex(name); @@ -572,6 +580,7 @@ __interface_add(const char *name, enum umdns_socket_type type, iface->ifindex = ifindex; iface->type = type; iface->addrs = *list; + iface->need_multicast = mcast; vlist_add(&interfaces, &iface->node, id_buf); return; diff --git a/interface.h b/interface.h index aca2f41..0c37736 100644 --- a/interface.h +++ b/interface.h @@ -52,6 +52,7 @@ struct interface { const char *name; enum umdns_socket_type type; + bool need_multicast; int ifindex; struct interface_addr_list addrs; -- 2.30.2